package org.rsbot.script.methods;

import java.awt.*;
import java.util.LinkedList;

import org.rsbot.script.wrappers.*;

public class Paint extends MethodProvider {
	private final LinkedList<MousePath> mousePath = new LinkedList<MousePath>();
	private final LinkedList<MouseClick> mouseClick = new LinkedList<MouseClick>();

	public Paint(final MethodContext ctx) {
		super(ctx);
	}

	private class MousePath extends Point {
		private static final long serialVersionUID = 1L;

		private long finishTime;

		public MousePath(int x, int y, int lastingTime) {
			super(x, y);
			finishTime = System.currentTimeMillis() + lastingTime;
		}

		public boolean isUp() {
			return System.currentTimeMillis() > finishTime;
		}
	}

	private class MouseClick extends Point {
		private static final long serialVersionUID = 1L;

		private long finishTime;

		public MouseClick(int x, int y, int lastingTime) {
			super(x, y);
			finishTime = System.currentTimeMillis() + lastingTime;
		}

		public boolean isUp() {
			return System.currentTimeMillis() > finishTime;
		}
	}

	/**
	 * Draws a progress bar using the co-ordinates, dimensions and skill
	 * provided. This also displays current level in the skill, percent till the
	 * next level & exp needed to reach the next level
	 * 
	 * @param g
	 *            An instance of Graphics to paint to.
	 * @param skill
	 *            The number of the skill wanting to display. E.g Skills.MAGIC
	 * @param x
	 *            The "x" co-ordinate.
	 * @param y
	 *            The "y" co-ordinate.
	 * @param w
	 *            The width of the progress bar.
	 * @param h
	 *            The height of the progress bar.
	 * @param b
	 *            The base color, normally red.
	 * @param o
	 *            The overlay color, normally green.
	 * @param t
	 *            The text color.
	 * @param op
	 *            The opacity of the bar. Range: (0 - 255)
	 * @author Fletch To 99, Rudday
	 */

	public void drawProgressBar(Graphics g, int skill, int x, int y, int w,
			int h, Color b, Color o, Color t, int op) {
		Graphics2D g2 = (Graphics2D) g;
		GradientPaint base = new GradientPaint(x, y, new Color(0, 0, 0, op), x,
				y + h + 3, b, true);
		GradientPaint overlay = new GradientPaint(x, y, new Color(0, 0, 0, op),
				x, y + h + 3, o, true);
		g2.setPaint(base);
		g2.fillRect(x, y, w, h);
		g2.setPaint(overlay);
		g2.fillRect(
				x,
				y,
				(int) (w * (methods.skills.getPercentToNextLevel(skill) / 100.0)),
				h);
		g2.setColor(Color.BLACK);
		g2.drawRect(x, y, w, h);
		g2.setFont(new Font("Arial", 0, 20));
		String progress = methods.skills.getPercentToNextLevel(skill) + "% to "
				+ (methods.skills.getCurrentLevel(skill) + 1) + " "
				+ Skills.SKILL_NAMES[skill] + " | "
				+ methods.skills.getExpToNextLevel(skill) + "XP Until level";
		g2.setColor(t);
		g2.drawString(
				progress,
				x + ((w - (g.getFontMetrics().stringWidth(progress))) / 2),
				(int) (y + ((g.getFontMetrics().getHeight() / 2) + (h / 4) * 1.65)));
	}

	/**
	 * Draws a oval where the clients cursor is.
	 * 
	 * @param g
	 *            An instance of Graphics to paint to.
	 * @param c
	 *            Color of the mouse to draw.
	 * @param click
	 *            Paint a string saying click where the user/script clicks.
	 * @param lastingTime
	 *            The length of the time "click" will appear for, (0 for false
	 *            click).
	 * @author Fletch To 99
	 */

	public void drawMouse(Graphics g, Color c, Boolean click, int lastingTime) {
		Point m = methods.mouse.getLocation();
		Point p = methods.mouse.getPressLocation();
		g.setColor(c);
		g.drawOval(m.x - 1, m.y - 1, 2, 2);
		g.drawOval(m.x - 5, m.y - 5, 10, 10);
		if (click) {
			while (!mouseClick.isEmpty() && mouseClick.peek().isUp())
				mouseClick.remove();
			MouseClick click1 = new MouseClick(p.x, p.y, lastingTime);
			if (mouseClick.isEmpty() || !mouseClick.getLast().equals(click1))
				mouseClick.add(click1);
			MouseClick lastPoint = null;
			for (MouseClick a : mouseClick) {
				if (lastPoint != null) {
					g.setColor(c);
					g.drawString("click", a.x - 13, a.y - 10);
				}
				lastPoint = a;
			}
		}
	}

	/**
	 * Draws a oval where the chosen Point is.
	 * 
	 * @param g
	 *            An instance of Graphics to paint to.
	 * @param c
	 *            Color of the mouse to draw.
	 * @param click
	 *            Paint a string saying click where the user/script clicks.
	 * @param p
	 *            Point to draw for.
	 * @param lastingTime
	 *            The length of the time "click" will appear for, (0 for false
	 *            click).
	 * @author Fletch To 99
	 */

	public void drawMouse(Graphics g, Color c, Boolean click, Point p,
			int lastingTime) {
		g.setColor(c);
		g.drawOval(p.x - 1, p.y - 1, 2, 2);
		g.drawOval(p.x - 5, p.y - 5, 10, 10);
		if (click) {
			while (!mouseClick.isEmpty() && mouseClick.peek().isUp())
				mouseClick.remove();
			MouseClick click1 = new MouseClick(p.x, p.y, lastingTime);
			if (mouseClick.isEmpty() || !mouseClick.getLast().equals(click1))
				mouseClick.add(click1);
			MouseClick lastPoint = null;
			for (MouseClick a : mouseClick) {
				if (lastPoint != null) {
					g.setColor(c);
					g.drawString("click", a.x - 13, a.y - 10);
				}
				lastPoint = a;
			}
		}
	}

	/**
	 * Draws a line where the clients cursor is.
	 * 
	 * @param g
	 *            An instance of Graphics to paint to.
	 * @param c
	 *            Color of the line to draw.
	 * @param lastingTime
	 *            The time for the line to stay on the screen.
	 * @author Fletch To 99
	 */

	public void drawMouseLine(Graphics g, Color c, int lastingTime) {
		Graphics2D g2 = (Graphics2D) g;
		Point m = methods.mouse.getLocation();
		while (!mousePath.isEmpty() && mousePath.peek().isUp())
			mousePath.remove();
		MousePath mp = new MousePath(m.x, m.y, lastingTime);
		if (mousePath.isEmpty() || !mousePath.getLast().equals(mp))
			mousePath.add(mp);
		MousePath lastPoint = null;
		for (MousePath a : mousePath) {
			if (lastPoint != null) {
				g2.setColor(c);
				g2.drawLine(a.x, a.y, lastPoint.x, lastPoint.y);
			}
			lastPoint = a;
		}
	}

	/**
	 * Draws a line where the clients cursor is.
	 * 
	 * @param g
	 *            An instance of Graphics to paint to.
	 * @param c
	 *            Color of the line to draw.
	 * @param lastingTime
	 *            The time for the line to stay on the screen.
	 * @param p
	 *            The chosen point to draw for.
	 * @author Fletch To 99
	 */

	public void drawMouseLine(Graphics g, Color c, int lastingTime, Point p) {
		Graphics2D g2 = (Graphics2D) g;
		while (!mousePath.isEmpty() && mousePath.peek().isUp())
			mousePath.remove();
		MousePath mp = new MousePath(p.x, p.y, lastingTime);
		if (mousePath.isEmpty() || !mousePath.getLast().equals(mp))
			mousePath.add(mp);
		MousePath lastPoint = null;
		for (MousePath a : mousePath) {
			if (lastPoint != null) {
				g2.setColor(c);
				g2.drawLine(a.x, a.y, lastPoint.x, lastPoint.y);
			}
			lastPoint = a;
		}
	}

	/**
	 * Draws the object of your choice.
	 * 
	 * @param g
	 *            An instance of Graphics to paint to.
	 * @param obj
	 *            Target object to color.
	 * @param c
	 *            Color to color the model.
	 * @author Fletch To 99
	 */

	public void drawObject(Graphics g, RSObject obj, Color c) {
		if (obj != null) {
			RSModel model = obj.getModel();
			if (model != null) {
				g.setColor(c);
				for (Polygon p : model.getTriangles()) {
					g.fillPolygon(p);
				}
			}
		}
	}

	/**
	 * Draws a npc of your choice.
	 * 
	 * @param g
	 *            An instance of Graphics to paint to.
	 * @param npc
	 *            Target NPC to color.
	 * @param c
	 *            Color to color the model.
	 * @author Fletch To 99
	 */

	public void drawNpc(Graphics g, RSNPC npc, Color c) {
		if (npc != null) {
			RSModel model = npc.getModel();
			if (model != null) {
				g.setColor(c);
				for (Polygon p : model.getTriangles()) {
					g.fillPolygon(p);
				}
			}
		}
	}

	/**
	 * Draws a player of your choice.
	 * 
	 * @param g
	 *            An instance of Graphics to paint to.
	 * @param p
	 *            Target player to color.
	 * @param c
	 *            Color to color the model.
	 * @author Fletch To 99
	 */

	public void drawPlayer(Graphics g, RSPlayer p, Color c) {
		if (p != null) {
			RSModel model = p.getModel();
			if (model != null) {
				g.setColor(c);
				for (Polygon p1 : model.getTriangles()) {
					g.fillPolygon(p1);
				}
			}
		}
	}

}